/*
 * To change this template, choose Tools | Templates and open the template in
 * the editor.
 */
package br.jm.acionista.view;

import br.jm.acionista.base.eao.EaoException;
import br.jm.acionista.entity.*;
import br.jm.acionista.filter.Funcoes;
import br.jm.acionista.relatorio.ReportUtil;
import br.jm.acionista.sistema.eao.ClienteEao;
import br.jm.acionista.sistema.eao.ClienteParticipacaoEao;
import br.jm.acionista.sistema.eao.EmpresaEao;
import java.io.Serializable;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import javax.faces.validator.ValidatorException;
import javax.persistence.EntityManager;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import net.sf.jasperreports.engine.JRException;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.LazyDataModel;

/**
 *
 * @author joao
 */
public class ClienteBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private Cliente selectedCliente;
    private ClienteParticipacao selectedClienteParticipacao;
    private ClienteParticipacaoPK selectedClienteParticipacaoPK;
    private CepEndereco cepEndereco;
    private Nacionalidade nacionalidade;
    private ClienteEao ClienteJpa;
    private ClienteParticipacaoEao ClienteParticipacaoJpa;
    private LazyDataModel<Cliente> lazyModel;
    private int nTotalReg;
    private String mascaraCpf;
    private SelectItem[] tipClienteOptions;
    private String[][] tipCliente = {{"F", "J"}, {"Física", "Jurídica"}};
    private FacesMessage msg;
    private Funcoes funcoes = new Funcoes();
    private Map<String, String> pesquisas = new HashMap<String, String>();
    private boolean editMode;
    private String labelRazNom;
    private String labelCnpj;
    private String labelDat;
    private EntityManager sessao;
    private String tipAcionista = "T";
    private String tipFiltro = "N";
    private String filtro = "";
    private String order = "R";
    private String orderTipo = "A";
    private boolean disable;
    private boolean disableGerencia;
    public HttpSession session;
    private Usuario usuarioAutenticado;
    private String cSql;
    private Empresa selectedEmpresa;
    private EmpresaEao empresaJpa;
    private Livro selectedLivro;
    private FacesContext ctx;

    public ClienteBean() {
        try {
            FacesContext ctx = FacesContext.getCurrentInstance();
            session = (HttpSession) ctx.getExternalContext().getSession(false);

            usuarioAutenticado = (Usuario) session.getAttribute("usuarioAutenticado");

            if (usuarioAutenticado.getIdUsuario() == 1) {
                this.disableGerencia = true;
            } else {
                this.disableGerencia = false;
            }

            this.editMode = false;
            this.disable = true;

            selectedLivro = new Livro();
            ClienteJpa = ClienteEao.getInstance();
            ClienteParticipacaoJpa = ClienteParticipacaoEao.getInstance();
            empresaJpa = EmpresaEao.getInstance();

            selectedCliente = new Cliente();
            selectedCliente.setIdCliente(0);

            tipClienteOptions = createFilterOptions(tipCliente);

            //CLIENTE
            lazyModel = new LazyDataModel<Cliente>() {
                private static final long serialVersionUID = 1L;

                @Override
                public List<Cliente> load(int first, int pageSize, String sortField, boolean sortOrder, Map<String, String> filters) {
                    List<Cliente> lazyCliente = new ArrayList<Cliente>();

                    try {
                        lazyCliente = ClienteJpa.getNative("Cliente", first, pageSize, sortField, sortOrder, filters, null);
                    } catch (Exception ex) {
                        Logger.getLogger(ClienteBean.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    return lazyCliente;
                }
            };

            nTotalReg = ClienteJpa.getCount("Cliente");
            lazyModel.setRowCount(nTotalReg);

        } catch (Exception ex) {
            Logger.getLogger(ClienteBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public LazyDataModel<Cliente> getLazyModel() {
        return lazyModel;
    }

    public void setLazyModel(LazyDataModel<Cliente> lazyModel) {
        this.lazyModel = lazyModel;
    }

    public Cliente getSelectedCliente() {
        if (selectedCliente == null) {
            selectedCliente = new Cliente();
        }
        return selectedCliente;
    }

    public void setSelectedCliente(Cliente selectedCliente) {
        this.selectedCliente = selectedCliente;
    }

    public void inserir(ActionEvent actionEvent) throws EaoException {
        msg = null;

        try {
            this.sessao = ClienteJpa.openSessaoLote();
            ClienteJpa.openTransaction(this.sessao);

            if (ValidaCampos("Inserir", "C")) {
                this.selectedCliente.setIdCliente(null);
                this.selectedCliente.setImpresso(0);

                ClienteJpa.create(selectedCliente, "S", this.sessao);

                ClienteJpa.closeTransaction(this.sessao);

                // Atualiza os percetuais de participacao
                selectedEmpresa = empresaJpa.getPorId(1);
                cSql = "update cliente "
                        + "set perc_partic = (qde_acao / ".concat(selectedEmpresa.getQdeTotal().toString()).concat(" ) * 100 ");
                ClienteJpa.executeUpdate(cSql);

                selectedClienteParticipacaoPK = new ClienteParticipacaoPK();
                selectedClienteParticipacaoPK.setDatPartic(new Date());
                selectedClienteParticipacaoPK.setIdCliente(selectedCliente.getIdCliente());

                selectedClienteParticipacao = ClienteParticipacaoJpa.getPorId(selectedClienteParticipacaoPK);

                if (selectedClienteParticipacao == null) {
                    selectedClienteParticipacao = new ClienteParticipacao();

                    selectedClienteParticipacao.setCliente(selectedCliente);
                    selectedClienteParticipacao.setClienteParticipacaoPK(selectedClienteParticipacaoPK);
                    selectedClienteParticipacao.setPercPartic(selectedCliente.getPercPartic());

                    ClienteParticipacaoJpa.create(selectedClienteParticipacao);

                    selectedClienteParticipacao = null;
                } else {
                    selectedCliente = ClienteJpa.getPorId(selectedCliente.getIdCliente());

                    selectedClienteParticipacao.setCliente(selectedCliente);
                    selectedClienteParticipacao.setClienteParticipacaoPK(selectedClienteParticipacaoPK);
                    selectedClienteParticipacao.setPercPartic(selectedCliente.getPercPartic());

                    ClienteParticipacaoJpa.edit(selectedClienteParticipacao);
                }

                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cliente Inserido com Sucesso", selectedCliente.getNomCliente());
            }
        } catch (Exception e) {
            if (this.sessao.isOpen()) {
                ClienteJpa.closeSessaoRollback(this.sessao);
            }
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Inserir: " + selectedCliente.getNomCliente(), "");
        } finally {
            this.sessao = null;

            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void alterar(ActionEvent actionEvent) throws EaoException {
        msg = null;

        try {
            //this.sessao = ClienteJpa.openSessaoLote();
            //ClienteJpa.openTransaction(this.sessao);

            if (ValidaCampos("Alterar", "C")) {

                ClienteJpa.edit(this.selectedCliente);

                // Atualiza os percetuais de participacao
                selectedEmpresa = empresaJpa.getPorId(1);
                String cTotal = selectedEmpresa.getQdeTotal().toString();
                cSql = "update cliente "
                        + "set perc_partic = (qde_acao / ".concat(cTotal).concat(" ) * 100 ");
                ClienteJpa.executeUpdate(cSql);

                selectedClienteParticipacaoPK = new ClienteParticipacaoPK();
                selectedClienteParticipacaoPK.setDatPartic(new Date());
                selectedClienteParticipacaoPK.setIdCliente(selectedCliente.getIdCliente());

                selectedClienteParticipacao = ClienteParticipacaoJpa.getPorId(selectedClienteParticipacaoPK);

                if (selectedClienteParticipacao == null) {
                    selectedClienteParticipacao = new ClienteParticipacao();

                    selectedClienteParticipacao.setCliente(selectedCliente);
                    selectedClienteParticipacao.setClienteParticipacaoPK(selectedClienteParticipacaoPK);
                    selectedClienteParticipacao.setPercPartic(selectedCliente.getPercPartic());

                    ClienteParticipacaoJpa.create(selectedClienteParticipacao);

                    selectedClienteParticipacao = null;
                } else {
                    selectedCliente = ClienteJpa.getPorId(selectedCliente.getIdCliente());

                    selectedClienteParticipacao.setCliente(selectedCliente);
                    selectedClienteParticipacao.setClienteParticipacaoPK(selectedClienteParticipacaoPK);
                    selectedClienteParticipacao.setPercPartic(selectedCliente.getPercPartic());

                    ClienteParticipacaoJpa.edit(selectedClienteParticipacao);
                }

                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cliente Alterado com Sucesso", selectedCliente.getNomCliente());
            }
        } catch (Exception e) {
            // if (this.sessao.isOpen()) {
            //    ClienteJpa.closeSessaoRollback(this.sessao);
            // }
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Alterar: " + selectedCliente.getNomCliente(), "");
        } finally {
            this.sessao = null;
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void excluir(ActionEvent actionEvent) throws EaoException {
        msg = null;

        try {
            this.sessao = ClienteJpa.openSessaoLote();
            ClienteJpa.openTransaction(sessao);

            cSql = "delete from cliente_participacao where id_cliente = ".concat(selectedCliente.getIdCliente().toString());
            ClienteParticipacaoJpa.executeUpdate(cSql, "S", this.sessao);

            ClienteJpa.destroy(selectedCliente, "S", this.sessao);

            ClienteJpa.closeTransaction(this.sessao);

            // Atualiza os percetuais de participacao
            selectedEmpresa = empresaJpa.getPorId(1);
            cSql = "update cliente "
                    + "set perc_partic = (qde_acao / ".concat(selectedEmpresa.getQdeTotal().toString()).concat(" ) * 100 ");
            ClienteJpa.executeUpdate(cSql);

            msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cliente Excluido com Sucesso", selectedCliente.getNomCliente());
        } catch (Exception e) {
            if (this.sessao.isOpen()) {
                ClienteJpa.closeSessaoRollback(this.sessao);
            }
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Excluir: " + selectedCliente.getNomCliente(), "");
        } finally {
            this.sessao = null;

            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void imprimeAcionista(ActionEvent actionEvent) {
        Map parametros = new HashMap();
        String cWhere = "";
        String cOrder = "";
        ReportUtil reportUtil = new ReportUtil();
        try {
            if (!this.tipAcionista.equals("T")) {
                cWhere = "WHERE cliente.\"tip_cliente\" = '".concat(this.tipAcionista).concat("' ");
            }

            if (!this.tipFiltro.equals("N")) {
                if (cWhere.contains("WHERE")) {
                    cWhere += " AND ";
                } else {
                    cWhere += " WHERE ";
                }
                if (this.tipFiltro.equals("C")) {
                    cWhere += "cliente.\"num_cpf\" like '%".concat(this.filtro).concat("%' ");
                } else {
                    cWhere += "cliente.\"nom_cliente\" like '%".concat(this.filtro).concat("%' ");
                }
            }

            if (!this.order.equals("N")) {
                if (this.tipFiltro.equals("C")) {
                    cWhere += "ORDER BY cliente.\"num_cpf\" ";
                } else {
                    cWhere += "ORDER BY cliente.\"nom_cliente\" ";
                }
            }

            if (!cWhere.isEmpty()) {
                parametros.put("PAR_WHERE", cWhere);
            }
            if (!cOrder.isEmpty()) {
                parametros.put("PAR_ORDER", cOrder);
            }

            reportUtil.executarRelatorio2("acionista.jasper", parametros);

            msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Relatório Impresso com Sucesso", "");
        } catch (JRException e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Imprimir o Relatório", "");
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Imprimir o Relatório", "");
        } finally {
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public Cliente limpar() {
        this.disable = false;
        this.selectedCliente = new Cliente();
        this.selectedCliente.setTipCliente("J");
        this.nacionalidade = new Nacionalidade();

        handleCpf();

        return this.selectedCliente;
    }

    public String getMascaraCpf() {
        if (mascaraCpf == null) {
            handleCpf();
        } else if (selectedCliente.getNumCpf() != null) {
            handleCpf();
        }
        return mascaraCpf;
    }

    public void setMascaraCpf(String mascaraCpf) {
        this.mascaraCpf = mascaraCpf;
    }

    public void handleCpf() {
        if (this.selectedCliente.getNumCpf() == null) {
            if (this.selectedCliente.getTipCliente() == null) {
                this.mascaraCpf = "99.999.999/9999-99";
            } else {
                if (this.selectedCliente.getTipCliente().equals("F")) {
                    this.mascaraCpf = "999.999.999-99";
                    this.editMode = false;
                } else {
                    this.mascaraCpf = "99.999.999/9999-99";
                    this.editMode = true;
                }
            }
        } else {
            if (this.selectedCliente.getTipCliente().equals("F")) {
                this.mascaraCpf = "999.999.999-99";
                this.editMode = false;
            } else {
                this.mascaraCpf = "99.999.999/9999-99";
                this.editMode = true;
            }
        }
    }

    public void onRowSelectNavigate(SelectEvent event) {
        try {
            nacionalidade = new Nacionalidade();
            nacionalidade = (Nacionalidade) event.getObject();

            this.selectedCliente.setIdNacionalidade(nacionalidade);
        } catch (Exception ex) {
            Logger.getLogger(BairroBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void onRowSelectNavigateEndereco(SelectEvent event) {
        try {
            cepEndereco = new CepEndereco();
            cepEndereco = (CepEndereco) event.getObject();

            if (cepEndereco != null) {
                this.selectedCliente.setCodLogradouro(cepEndereco);
            }
        } catch (Exception ex) {
            Logger.getLogger(BairroBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            cepEndereco = null;
        }
    }

    private SelectItem[] createFilterOptions(String[][] tipClientes) {
        SelectItem[] options = new SelectItem[3];

        options[0] = new SelectItem("", "Selecione");
        for (int i = 0; i < 2; i++) {
            options[i + 1] = new SelectItem(tipClientes[0][i], tipClientes[1][i]);
        }

        return options;
    }

    public String[][] getTipCliente() {
        return tipCliente;
    }

    public void setTipCliente(String[][] tipCliente) {
        this.tipCliente = tipCliente;
    }

    public SelectItem[] getTipClienteOptions() {
        return tipClienteOptions;
    }

    public void setTipClienteOptions(SelectItem[] tipClienteOptions) {
        this.tipClienteOptions = tipClienteOptions;
    }

    public boolean verificaCampo(FacesContext context, UIComponent input, Object value) throws ValidatorException {
        try {
            String cCampo = (String) value;
            if (cCampo.isEmpty()) {
                throw new ValidatorException(new FacesMessage("Campo Obrigatório"));
            }
        } catch (Exception e) {
            throw new ValidatorException(new FacesMessage("Campo Obrigatório"));
        }

        return true;
    }

    public boolean ValidaCampos(String cOperacao, String cModulo) {
        boolean lReturn = true;
        msg = null;
        String[] aCaractere = {".", "/", "-"};
        String[] aTipCliente = {"J", "F"};

        String cCpf;
        try {
            if (cModulo.equals("C")) {
                if (!funcoes.PesqCaracteres(selectedCliente.getTipCliente(), aTipCliente)) {
                    msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao ".concat(cOperacao).concat(": ").concat(selectedCliente.getNomCliente()).concat(" Tipo do Cliente não selecionado!"), null);
                    lReturn = false;
                }

                if (lReturn) {
                    if (selectedCliente.getNomCliente().isEmpty()) {
                        msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao ".concat(cOperacao).concat(": ").concat(selectedCliente.getNomCliente()).concat(" Nome do Cliente em branco!"), null);
                        lReturn = false;
                    }
                }

                if (lReturn) {
                    cCpf = funcoes.TiraCaractere(selectedCliente.getNumCpf(), aCaractere);
                    lReturn = funcoes.valida_CpfCnpj(cCpf);
                    if (lReturn) {
                        selectedCliente.setNumCpf(cCpf);
                    } else {
                        msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao ".concat(cOperacao).concat(": ").concat(selectedCliente.getNomCliente()).concat(" C.N.P.J. ou C.P.F. Inválido!"), null);
                        lReturn = false;
                    }
                }

                if (lReturn) {
                    if (this.selectedCliente.getTipCliente().equals("F")) {
                        if (this.selectedCliente.getIdNacionalidade() == null) {
                            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao ".concat(cOperacao).concat(": ").concat(selectedCliente.getNomCliente()).concat(" Nacionalidade Obrigatória!"), null);
                            lReturn = false;
                        }
                    } else {
                        this.selectedCliente.setIdNacionalidade(null);
                    }
                }

                if (lReturn) {
                    if (selectedCliente.getCodLogradouro() == null) {
                        if (selectedCliente.getIdCliente() != null) {
                            Cliente clienteTemp = ClienteJpa.getPorId(selectedCliente.getIdCliente());
                            selectedCliente.setCodLogradouro(clienteTemp.getCodLogradouro());
                            cepEndereco = null;
                        } else {
                            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao ".concat(cOperacao).concat(": ").concat(selectedCliente.getNomCliente()).concat(" Endereço não definido!"), null);
                            lReturn = false;
                        }
                    }
                }

                if (lReturn) {
                    if (selectedCliente.getNumEndereco().replace(" ", "").isEmpty()) {
                        msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao ".concat(cOperacao).concat(": ").concat(selectedCliente.getNomCliente()).concat(" Numero do Endereço não definido!"), null);
                        lReturn = false;
                    }
                }
            }
        } catch (Exception ex) {
            lReturn = false;
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao ".concat(cOperacao).concat(": ").concat(selectedCliente.getNomCliente()), null);
        }
        return lReturn;
    }

    public boolean isEditMode() {
        if (selectedCliente.getTipCliente() == null) {
            this.editMode = true;
        } else {
            if (selectedCliente.getTipCliente().equals("J")) {
                this.editMode = true;
            } else {
                this.editMode = false;
            }
        }
        return editMode;
    }

    public void setEditMode(boolean editMode) {
        this.editMode = editMode;
    }

    public String getLabelRazNom() {
        if (selectedCliente.getTipCliente() == null) {
            this.labelRazNom = "Razão Social:";
        } else {
            if (selectedCliente.getTipCliente().equals("J")) {
                this.labelRazNom = "Razão Social:";
            } else {
                this.labelRazNom = "Nome:";
            }
        }
        return labelRazNom;
    }

    public void setLabelRazNom(String labelRazNom) {
        this.labelRazNom = labelRazNom;
    }

    public String getLabelCnpj() {
        if (selectedCliente.getTipCliente() == null) {
            this.labelCnpj = "C.N.P.J.:";
        } else {
            if (selectedCliente.getTipCliente().equals("J")) {
                this.labelCnpj = "C.N.P.J.:";
            } else {
                this.labelCnpj = "C.P.F.:";
            }
        }
        return labelCnpj;
    }

    public void setLabelCnpj(String labelCnpj) {
        this.labelCnpj = labelCnpj;
    }

    public String getLabelDat() {
        if (selectedCliente.getTipCliente() == null) {
            this.labelDat = "Data Abertura:";
        } else {
            if (selectedCliente.getTipCliente().equals("J")) {
                this.labelDat = "Data Abertura:";
            } else {
                this.labelDat = "Data Nascimento:";
            }
        }
        return labelDat;
    }

    public void setLabelDat(String labelDat) {
        this.labelDat = labelDat;
    }

    public String getFiltro() {
        return filtro;
    }

    public void setFiltro(String filtro) {
        this.filtro = filtro;
    }

    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
    }

    public String getTipAcionista() {
        return tipAcionista;
    }

    public void setTipAcionista(String tipAcionista) {
        this.tipAcionista = tipAcionista;
    }

    public String getTipFiltro() {
        return tipFiltro;
    }

    public void setTipFiltro(String tipFiltro) {
        this.tipFiltro = tipFiltro;
    }

    public void reportCreate(ActionEvent ae) {

        String url = "/relatorio";
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            ServletContext sc = (ServletContext) context.getExternalContext().getContext();
            RequestDispatcher rd = sc.getRequestDispatcher(url);

            HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
            HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();

            //parametros para geraçao do relatorio  
            request.setAttribute("tipAcionista", tipAcionista);
            request.setAttribute("tipFiltro", tipFiltro);
            request.setAttribute("filtro", filtro);
            request.setAttribute("order", order);

            rd.forward(request, response);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            context.responseComplete();
        }

    }

    public boolean isDisable() {
        return disable;
    }

    public void setDisable(boolean disable) {
        this.disable = disable;
    }

    public void onRowSelectCliente(SelectEvent event) {
        this.disable = true;
    }

    public boolean isDisableGerencia() {
        return disableGerencia;
    }

    public void setDisableGerencia(boolean disableGerencia) {
        this.disableGerencia = disableGerencia;
    }

    public Livro getSelectedLivro() {
        return selectedLivro;
    }

    public void setSelectedLivro(Livro selectedLivro) {
        if (selectedLivro != null) {
            this.selectedCliente.setIdLivro(selectedLivro);
        }
        this.selectedLivro = selectedLivro;
    }

    public String getOrderTipo() {
        return orderTipo;
    }

    public void setOrderTipo(String orderTipo) {
        this.orderTipo = orderTipo;
    }

    public void gerarRelatorio(ActionEvent actionEvent) {
        try {
            ctx = FacesContext.getCurrentInstance();
            session = (HttpSession) ctx.getExternalContext().getSession(false);
            session.setAttribute("tipAcionista", tipAcionista);
            session.setAttribute("orderTipo", orderTipo);
            session.setAttribute("order", order);

            for (int i = 0; i < 600000000; i++) {
                String cTeste = "";
            }
            msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Relatório Gerado com Sucesso!", "");
        } catch (Exception ex) {
            msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Erro na Geração do Relatório!!", "");
        } finally {
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }
}
